<script lang="ts" setup generic="T extends object">
import type { CheckboxValueType } from "element-plus";
import { reactive, ref, watchEffect, type Ref } from "vue";

type State = { value?: number[]; valueKey: PropertyKey; titleKey: PropertyKey };

const state = reactive<State>({ value: [], valueKey: "id", titleKey: "name" });
const data = ref<T[]>([]) as Ref<T[]>;
const props = defineProps<{ modelValue?: number[]; list?: T[]; valueKey?: keyof T; titleKey?: keyof T }>();
const emits = defineEmits<{ (event: "update:modelValue", value?: number[]): void; (event: "link", value: T): void }>();

watchEffect(() => {
  if (props.modelValue) state.value = props.modelValue;
  if (props.valueKey) state.valueKey = props.valueKey;
  if (props.titleKey) state.titleKey = props.titleKey;
  if (props.list) data.value = props.list;
});

function get(item: T, key: PropertyKey) {
  return Reflect.get(item, key) || "";
}

function change(val: CheckboxValueType[]) {
  emits("update:modelValue", val as number[]);
}

function handleClick(item: T, payload: MouseEvent) {
  const links = document.querySelectorAll(".list-picker .actived");
  links.forEach((l) => l.classList.remove("actived"));

  const el = payload.target as HTMLElement;
  el.classList.add("actived");
  emits("link", item);
}
</script>

<template>
  <div class="list-picker">
    <el-checkbox-group v-model="state.value" @change="change">
      <el-row v-for="(item, index) in data" :key="index">
        <el-col :span="4" class="lt"><el-checkbox :label="get(item, state.valueKey)"></el-checkbox></el-col>
        <el-col :span="20" class="rt" @click.stop="(payload) => handleClick(item, payload)">
          <span>{{ get(item, state.titleKey) }}</span>
        </el-col>
      </el-row>
    </el-checkbox-group>
  </div>
</template>

<style lang="scss" scoped>
.list-picker {
  position: relative;
  border: 1px solid var(--vxe-input-border-color);
  border-radius: var(--vxe-border-radius);
  padding: 5px 10px;
  width: 100%;
  height: 100%;
  overflow-x: hidden;
  overflow-y: auto;

  .el-checkbox-group {
    font-size: inherit;
    line-height: inherit;
  }

  .el-row {
    border-bottom: 1px solid var(--vxe-input-border-color);
    height: 32px;

    .lt {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 32px;
    }

    .rt {
      display: inline-flex;
      align-items: center;
      cursor: pointer;
      height: 32px;
    }

    .rt:hover,
    .actived {
      color: var(--el-color-primary);
    }
  }

  :deep(.el-checkbox__label) {
    display: none;
  }
}
</style>
